package com.idealighter.game.roomcard.manager;

import com.google.common.eventbus.Subscribe;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import com.idealighter.game.event.manager.EventMgr;
import com.idealighter.game.roomcard.struct.RoomCardGameCfg;
import com.idealighter.game.roomcard.struct.RoomCardGameCfgMap;
import com.idealighter.game.roomcard.struct.RoomCardGameCfgValue;
import com.idealighter.game.roomcard.struct.convert.RoomCardGameCfgConvert;
import com.idealighter.game.schedule.manager.ScheduleMgr;
import com.idealighter.game.server.ExecutorMgr;
import com.idealighter.game.server.db.datadb.generate.domain.RoomCardGameCfgDomain;
import com.idealighter.game.server.db.datadb.generate.domain.RoomCardGameCfgDomainExample;
import com.idealighter.game.server.db.datadb.mapper.RoomCardGameCfgMapper;
import com.idealighter.game.server.event.ShutdownEvent;
import com.idealighter.utils.check.EmptyUtil;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Singleton
public class RoomCardGameCfgMgrScript {
  // 房卡游戏列表数据库操作
  private RoomCardGameCfgMapper roomCardGameCfgMapper;
  private Map<Integer, RoomCardGameCfg<? extends RoomCardGameCfgValue>> gameCfgMap =
      new ConcurrentHashMap<Integer, RoomCardGameCfg<? extends RoomCardGameCfgValue>>();
  private static final Logger LOG = LoggerFactory.getLogger(RoomCardGameCfgMgrScript.class);

  @Inject
  private ExecutorMgr executorMgr;

  /**
   * 构造函数.
   */
  @Inject
  public RoomCardGameCfgMgrScript(RoomCardGameCfgMapper roomCardGameCfgMapper,
      ScheduleMgr scheduleMgr, EventMgr eventMgr) {
    this.roomCardGameCfgMapper = roomCardGameCfgMapper;
    eventMgr.register(this);
    // 加载配置数据
    try {
      loadData();
    } catch (Exception e) {
      LOG.error("获取房卡游戏配置失败", e);
      System.exit(0);
    }
  }

  // 加载数据
  private void loadData() throws InstantiationException, IllegalAccessException {
    RoomCardGameCfgDomainExample example = new RoomCardGameCfgDomainExample();
    example.setOrderByClause("id asc");
    List<RoomCardGameCfgDomain> gameCfgs =
        roomCardGameCfgMapper.selectByExampleWithBLOBs(example);
    if (EmptyUtil.listIsNotEmpty(gameCfgs)) {
      for (RoomCardGameCfgDomain gameCfg : gameCfgs) {
        // 创建实力
        RoomCardGameCfg<? extends RoomCardGameCfgValue> gameCfgObject =
            RoomCardGameCfgMap.getGameCfgByGameId(gameCfg.getGameId()).newInstance();
        // 设置实例值
        RoomCardGameCfgConvert.INSTANCE.po2bo(gameCfgObject, gameCfg);
        // 添加到map
        gameCfgMap.put(gameCfg.getGameId(), gameCfgObject);
      }
    }
  }

  public List<RoomCardGameCfg<? extends RoomCardGameCfgValue>> findAllGameCfg() {
    return new ArrayList<RoomCardGameCfg<? extends RoomCardGameCfgValue>>(gameCfgMap.values());
  }

  @SuppressWarnings("unchecked")
  public <T extends RoomCardGameCfg<? extends RoomCardGameCfgValue>> T findGameCfg(Integer gameId,
      Class<T> claz) {
    return (T) gameCfgMap.get(gameId);
  }

  /**
   * @Title updateGameCfg.
   * @Description 更新游戏配置
   * @date 2018年6月14日 下午4:24:00
   * @param cfg 配置.
   */
  public void updateGameCfg(RoomCardGameCfg<? extends RoomCardGameCfgValue> cfg) {
    if (cfg != null) {
      executorMgr.getRoomCardExecutor(cfg.getGameId()).execute(() -> {
        updateGameCfgToDb(cfg);
        gameCfgMap.put(cfg.getGameId(), cfg);
      });
    }
  }

  /**
   * @Title removeGameCfg.
   * @Description 删除游戏配置
   * @date 2018年6月14日 下午4:24:25
   * @param gameId .
   */
  public void removeGameCfg(Integer gameId) {
    executorMgr.getRoomCardExecutor(gameId).execute(() -> {
      if (gameCfgMap.containsKey(gameId)) {
        RoomCardGameCfg<? extends RoomCardGameCfgValue> record = gameCfgMap.remove(gameId);
        roomCardGameCfgMapper.deleteByPrimaryKey(record.getId());
        gameCfgMap.remove(gameId);
      }
    });
  }

  /**
   * @Title saveAllGameCfg.
   * @Description 保存所有的游戏配置
   * @author houdongsheng
   * @date 2018年5月4日 上午11:01:09
   */
  private void saveAllGameCfg() {
    for (RoomCardGameCfg<? extends RoomCardGameCfgValue> cfg : gameCfgMap.values()) {
      updateGameCfgToDb(cfg);
    }
  }

  private void updateGameCfgToDb(RoomCardGameCfg<? extends RoomCardGameCfgValue> cfg) {
    RoomCardGameCfgDomain record = RoomCardGameCfgConvert.INSTANCE.bo2po(cfg);
    if (gameCfgMap.containsKey(cfg.getGameId())) {
      roomCardGameCfgMapper.updateByPrimaryKeyWithBLOBs(record);
    } else {
      roomCardGameCfgMapper.insertSelective(record);
      cfg.setId(record.getId());
    }
  }

  /**
   * @Title onShutDown.
   * @Description 捕捉关闭事件
   * @date 2018年6月14日 下午4:24:43
   * @param event .
   */
  @Subscribe
  public void onShutDown(ShutdownEvent event) {
    LOG.info("保存房卡游戏列表数据中...");
    saveAllGameCfg();
    LOG.info("保存房卡游戏列表成功");
  }
}
